using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;

namespace FreeFlow.Administration
{
  /// <summary>
  /// The type of a stage
  /// </summary>
  public enum StageType
  {
    /// <summary>Unknown stage type</summary>
    None=0,
    /// <summary>User stage</summary>
    User = 1,
    /// <summary>Group stage</summary>
    Group = 2,
    /// <summary>System stage</summary>
    System = 3,
    /// <summary>Archive stage</summary>
    Archive = 4,
    /// <summary>Sub-procedure stage</summary>
    SubProcedure = 5,
    /// <summary>Map segment stage</summary>
    MapSegment = 6,
    /// <summary>Rule stage</summary>
    Rules = 8,
    /// <summary>Start stage</summary>
    Start = 1024,
    /// <summary>Common stage</summary>
    Common = 1025
  }

  /// <summary>
  /// A stage in a map.
  /// </summary>
  public class Stage : DatabaseAware, IRefreshable
  {
    private Map map;
    private List<string> folderPages;
    internal Stage(Server server, Map map, IDataReader reader) : base(server)
    {
      this.map = map;
      name = reader["eStageName"].ToString();
      stageType = (StageType)Convert.ToInt16(reader["eStageType"]);
      todoList = reader["eToDoList"].ToString();
      watchList = reader["eTrackList"].ToString();
      whenStarted = reader["eOnEntry"].ToString();
      whenCompleted = reader["eOnExit"].ToString();
      priority = Convert.ToInt16(reader["ePriority"]);
      
      // read folder pages
      folderPages = new List<string>();
      string folderPagesString = reader["eFolderPages"].ToString();
      string[] folderPagesArray = folderPagesString.Split(',');
      for (int i = 0; i < folderPagesArray.Length; i++)
      {
        if (!string.IsNullOrEmpty(folderPagesArray[i]))
          folderPages.Add(folderPagesArray[i]); 
      }
    }

    private string name;
    /// <summary>
    /// Gets the name of the stage.
    /// </summary>
    public string Name
    {
      get
      {
        return name;
      }
    }

    private StageType stageType;
    /// <summary>
    /// Gets the type of the stage.
    /// </summary>
    public StageType StageType
    {
      get
      {
        return stageType;
      }
    }

    private string todoList;
    /// <summary>
    /// Gets the code that evaluates which users will have this stage on their To Do list.
    /// </summary>
    public string ToDoList
    {
      get
      {
        return todoList;
      }
    }

    private string watchList;
    /// <summary>
    /// Gets the code that evaluates which users will have this stage on their Watch list.
    /// </summary>
    public string WatchList
    {
      get
      {
        return watchList;
      }
    }

    private string whenStarted;
    /// <summary>
    /// Gets the code evaluated when the stage starts.
    /// </summary>
    public string WhenStarted
    {
      get
      {
        return whenStarted;
      }
    }

    private string whenCompleted;
    /// <summary>
    /// Gets the code evaluated when the stage is completed.
    /// </summary>
    public string WhenCompleted
    {
      get
      {
        return whenCompleted;
      }
    }

    private int priority;
    /// <summary>
    /// Gets the priority of the stage (as defined in the Designer's 'Stages Order' property).
    /// </summary>
    public int Priority
    {
      get
      {
        return priority;
      }
    }

    private FolderCollection folders;
    /// <summary>
    /// Gets the folders at this stage.
    /// </summary>
    public FolderCollection Folders
    {
      get
      {
        if (folders == null)
          folders = new FolderCollection(Server, map, name);
        return folders;
      }
    }

    private ActionCollection actions;
    /// <summary>
    /// Gets the actions available from this stage.
    /// </summary>
    public ActionCollection Actions
    {
      get
      {
        if (actions == null)
          actions = new ActionCollection(Server, map.Name, name);
        return actions;
      }
    }

    /// <summary>
    /// Gets the number of folder pages that will be displayed at this stage.
    /// </summary>
    public int FolderPageCount
    {
      get
      {
        return folderPages.Count;
      }
    }

    /// <summary>
    /// Gets the name of the folder page at the specified index.
    /// </summary>
    /// <param name="index">The index.</param>
    public string FolderPage(int index)
    {
      return (string)folderPages[index];
    }

    #region IRefreshable Members

    /// <summary>
    /// Refreshes the data for this stage.
    /// </summary>
    public void Refresh()
    {
      // TODO - reload stage properties
      folders = null;
      actions = null;
      foldersPassThroughCount = -1;
      eventCount = -1;
    }

    #endregion

    internal int foldersPassThroughCount = -1;
    /// <summary>
    /// Gets the number of folders that have passed through this stage.
    /// </summary>
    public int FoldersPassThroughCount
    {
      get
      {
        if (foldersPassThroughCount == -1)
          map.GetStatistics();
        return foldersPassThroughCount;
      }
    }

    internal int eventCount = -1;
    /// <summary>
    /// Gets the number of events that have occurred with this stage.
    /// </summary>
    public int EventCount
    {
      get
      {
        if (eventCount == -1)
          map.GetStatistics();

        return eventCount;
      }
    }

    internal TimeSpan averageTime = TimeSpan.MinValue;
    /// <summary>
    /// Gets the average time that folders spend at this stage.
    /// </summary>
    public TimeSpan AverageTime
    {
      get
      {
        if (averageTime == TimeSpan.MinValue)
          map.GetStatistics();

        return averageTime;
      }
    }
  }
}
